#ifndef NctiPyArgList_H
#define NctiPyArgList_H
#include "dcl_ncti_pubfun.h"
#include <Python.h>
#include "NctiTestSystemObject.h"
#include "NctiComDefine.h"
#include "NctiTransf.h"
#include "NctiRGBAColor.h"

namespace NCTI
{
	class DECL_NCTI_PUBFUN NctiPyArgList
	{
	public:
		NctiPyArgList(PyObject* pyArg, NctiPyErrorInfo* i_ErrorInfo);
		NctiPyArgList(PyObject* pyArg);
		virtual ~NctiPyArgList();
	private:
		PyObject* m_PyObject;
		NctiPyErrorInfo* m_ErrorInfo;
	public:
		Ncti_Integer Size();
		Ncti_Boolean IsNull();
		void ClearErrorInfo();
		Ncti_Boolean GetDouble(const Ncti_Integer& i_index, Ncti_Double& o_db);
		Ncti_Boolean GetBoolean(const Ncti_Integer& i_index, Ncti_Boolean& o_bo);
		Ncti_Boolean GetLong(const Ncti_Integer& i_index, Ncti_Long& o_long);
		Ncti_Boolean GetLong(const Ncti_Integer& i_index, Ncti_Integer& o_long);
		Ncti_Boolean GetStr(const Ncti_Integer& i_index, const Ncti_Char*& str);
		Ncti_Boolean GetStr(const Ncti_Integer& i_index, std::string& str);
        Ncti_Boolean GetColor(const Ncti_Integer& i_index, RGBAColor& o_color);
		Ncti_Boolean GetPosition(const Ncti_Integer& i_index, NctiPosition& o_position);
		Ncti_Boolean GetVector(const Ncti_Integer& i_index, NctiVector& o_vec);
		Ncti_Boolean GetList(const Ncti_Integer& i_index, PyObject*& pList);
		Ncti_Boolean GetDict(const Ncti_Integer& i_index, PyObject*& pDict);
		Ncti_Boolean GetFloatList(const Ncti_Integer& i_index, std::vector<Ncti_Float>& o_dbVec);
		Ncti_Boolean GetDoubleList(const Ncti_Integer& i_index, std::vector<Ncti_Double>& o_dbVec);
		Ncti_Boolean GetDoubleListList(const Ncti_Integer& i_index, std::vector < std::vector<Ncti_Double>>& o_dbVec);

        Ncti_Boolean GetPositionList(const Ncti_Integer& i_index, std::vector<Ncti_Float>& o_posVec);
		Ncti_Boolean GetPositionList(const Ncti_Integer& i_index, std::vector<NctiPosition>& o_posVec);
		Ncti_Boolean GetPositionListList(const Ncti_Integer& i_index, std::vector<std::vector<NctiPosition>>& o_posVec);
		Ncti_Boolean GetVectorList(const Ncti_Integer& i_index, std::vector<NctiVector>& o_ncvVec);
        Ncti_Boolean GetVectorList(const Ncti_Integer& i_index, std::vector<Ncti_Float>& o_ncvVec);

        Ncti_Boolean GetStrList(const Ncti_Integer& i_index, std::vector<std::string>& o_strVec);
		Ncti_Boolean GetDictDouble(const Ncti_Integer& i_index, std::string KeyName, Ncti_Double& o_db);
		Ncti_Boolean GetDictLong(const Ncti_Integer& i_index, std::string KeyName, Ncti_Long& o_long);
		Ncti_Boolean GetDictLongList(const Ncti_Integer& i_index, std::string KeyName, std::vector<Ncti_Long>& o_longVec);
		Ncti_Boolean GetDictLongLongList(const Ncti_Integer& i_index, std::string KeyName, std::vector<Ncti_LongLong>& o_longVec);
		Ncti_Boolean GetDictBoolean(const Ncti_Integer& i_index, std::string KeyName, Ncti_Boolean& o_bool);
		Ncti_Boolean GetDictStr(const Ncti_Integer& i_index, std::string KeyName, std::string& o_str);
		Ncti_Boolean GetDictStrPairs(const Ncti_Integer& i_index, std::map<std::string, std::string>& o_pairs);
		Ncti_Boolean IsNone(const Ncti_Integer & i_index);
		Ncti_Boolean GetDisplayObject(const Ncti_Integer & i_index, NctiDisplayObject*& pDisplayObject);
		Ncti_Boolean GetDisplayObjects(const Ncti_Integer & i_index, std::vector<NctiDisplayObject*>& pDisplayObjects);
		Ncti_Boolean GetDictDisplayObject(const Ncti_Integer& i_index, const std::string& KeyName, NctiDisplayObject*& pDisplayObject);

		Ncti_Boolean GetTransform(const Ncti_Integer& i_index, NctiTransf& o_transf);
		Ncti_Boolean GetTransformList(const Ncti_Integer& i_index, std::vector<NctiTransf>& o_vtTransf);

		template<typename T>
		Ncti_Boolean GetLongList(const Ncti_Integer& i_index, std::vector<T>& o_longVec)
		{
			ClearErrorInfo();
			if (Size() > i_index)
			{
				Ncti_Integer num = 0;
				PyObject* argValue = PyTuple_GetItem(m_PyObject, i_index);
				Ncti_Boolean isList = PyList_Check(argValue);
				if (isList)
				{
					num = PyList_Size(argValue);
					for (size_t i = 0; i < PyList_Size(argValue); i++)
					{
						PyObject* argData = PyList_GetItem(argValue, i);
						if (PYCHECK_NUMBER(argData))
						{
							T olong = PyLong_AsLong(argData);
							o_longVec.push_back(olong);
						}
					}
				}
				if (!isList ||o_longVec.size() != num)
				{
					m_ErrorInfo->m_ErrorCode = PY_ARGUMENT_TYPE_ERROR;
					m_ErrorInfo->m_ErrorIndex = i_index;
					m_ErrorInfo->m_correctType.push_back(PY_DATA_LIST_NUMBER);
					return false;
				}
				else
					return true;
			}
			return false;
		}
	};
	class DECL_NCTI_PUBFUN NctiPyArgItem
	{
	public:
		NctiPyArgItem(PyObject* pyArg, NctiPyErrorInfo* i_ErrorInfo);
		NctiPyArgItem(PyObject* pyArg);
		virtual ~NctiPyArgItem();
		Ncti_Boolean GetDictStr(std::string KeyName, std::string& o_str);
		Ncti_Boolean GetDictLong(std::string KeyName, Ncti_Long& o_long);
		Ncti_Boolean GetDictDouble(std::string KeyName, Ncti_Double& o_db);
		Ncti_Boolean GetDictPosition(std::string KeyName, NctiPosition& o_position);
		Ncti_Boolean GetDictVector(std::string KeyName, NctiVector& o_vec);
		Ncti_Boolean GetDictDisplayObject(std::string KeyName, NctiDisplayObject*& o_obj);
		void ClearErrorInfo();
	private:
		PyObject* m_PyObject;
		NctiPyErrorInfo* m_ErrorInfo;
	};
}
#endif // !NctiPyArgList_H
